<!DOCTYPE html>
<html>
<head>
  <title>stagger | anime.js</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:title" content="anime.js">
  <meta property="og:url" content="https://animejs.com">
  <meta property="og:description" content="Javascript Animation Engine">
  <meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="anime.js">
  <meta name="twitter:site" content="@juliangarnier">
  <meta name="twitter:description" content="Javascript Animation Engine">
  <meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
  <link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
  <link rel="icon" type="image/png" href="../assets/img/favicon.png" >
  <link href="../assets/css/animejs.css" rel="stylesheet">
  <link href="../assets/css/documentation.css" rel="stylesheet">
  <style>

    body {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
    }

    .testarea {
      display: flex;
      flex-direction: row;
      align-items: center;
      flex-wrap: wrap;
      flex-shrink: 0;
      width: 100%;
      height: 100%;
    }

    .demo {
      position: relative;
      flex-wrap: wrap;
      align-items: center;
      flex-grow: 1;
      width: 14rem;
      height: 4rem;
      padding: 2rem;
      border-bottom: none;
    }

    .demo h1 {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      text-align: center;
    }

    .demo div {
      width: 1rem;
      height: 1rem;
      /*background-color: currentColor;*/
      border: 2px solid currentColor;
    }

    .demo .grid-wrapper {
      position: relative;
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      width: 10rem;
      height: 5rem;
      margin: auto;
      border: none;
    }

    /* Player animation */

    .timeline {
      opacity: .2;
      position: fixed;
      flex-shrink: 0;
      width: 100%;
      height: 100%;
      padding-top: 4px;
    }

    .timeline.player-animation {
      width: 100%;
      left: 0;
    }

    .tl-needle {
      position: fixed;
      z-index: 2;
      top: 0;
      left: 0;
      width: 2px;
      height: 100%;
      margin-left: -1px;
      background-color: #FFF;
    }

    .tl-animation {
      position: relative;
      display: flex;
      justify-content: space-between;
      width: auto;
      height: 2px;
      margin-bottom: 2px;
      background-color: currentColor;
      border-radius: .5rem;
    }

    .tl-delay,
    .tl-end-delay {
      width: auto;
      height: 100%;
      background-color: rgba(0,0,0,.5);
    }

  </style>
</head>
<body>

  <div class="player-animation"></div>

  <div class="testarea">

    <section class="demo normal">
      <h1>Normal</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo normal-reversed">
      <h1>Normal reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-last">
      <h1>From last</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-last-reversed">
      <h1>From last reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-center">
      <h1>From center</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-center-reversed">
      <h1>From center reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-index">
      <h1>From index</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo from-index-reversed">
      <h1>From index reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range">
      <h1>Range</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range-reversed">
      <h1>Range reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range-from-last">
      <h1>Range from last</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range-from-last-reversed">
      <h1>Range from last reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range-from-center">
      <h1>Range from center</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo range-from-center-reversed">
      <h1>Range from center reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo easing">
      <h1>Easing</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo easing-reversed">
      <h1>Easing reversed</h1>
      <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    </section>

    <section class="demo">
      <h1>Coordinates</h1>
      <div class="grid-wrapper grid">
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
      </div>
    </section>

    <section class="demo">
      <h1>Coordinates reversed</h1>
      <div class="grid-wrapper grid-reversed">
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
      </div>
    </section>

    <section class="demo">
      <h1>Coordinates reversed</h1>
      <div class="grid-wrapper grid-axis">
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
      </div>
    </section>

    <section class="demo">
      <h1>Coordinates reversed</h1>
      <div class="grid-wrapper grid-axis-reversed">
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
      </div>
    </section>

  </div>

</body>
<script type="module">

  import anime from '../../src/index.js';

  var animations = anime.timeline({
    easing: 'easeInOutQuad',
    // direction: 'alternate',
    loop: true
  })
  .add({
    targets: '.normal div',
    translateY: anime.stagger('-.5em'),
    delay: anime.stagger(200)
  }, 0)
  .add({
    targets: '.normal-reversed div',
    translateY: anime.stagger('-.5em', { direction: 'reverse' }),
    delay: anime.stagger(200, { direction: 'reverse' }),
  }, 0)
  .add({
    targets: '.from-last div',
    translateY: anime.stagger('-.5em', {from: 'last'}),
    delay: anime.stagger(200, {from: 'last'})
  }, 0)
  .add({
    targets: '.from-last-reversed div',
    translateY: anime.stagger('-.5em', { from: 'last', direction: 'reverse' }),
    delay: anime.stagger(200, { from: 'last', direction: 'reverse' }),
  }, 0)
  .add({
    targets: '.from-center div',
    translateY: anime.stagger('-.5em', {from: 'center'}),
    delay: anime.stagger(200, {from: 'center'})
  }, 0)
  .add({
    targets: '.from-center-reversed div',
    translateY: anime.stagger('-.5em', { from: 'center', direction: 'reverse' }),
    delay: anime.stagger(200, { from: 'center', direction: 'reverse' }),
  }, 0)
  .add({
    targets: '.from-index div',
    translateY: anime.stagger('-.5em', {from: 3}),
    delay: anime.stagger(200, {from: 3})
  }, 0)
  .add({
    targets: '.from-index-reversed div',
    translateY: anime.stagger('-.5em', { from: 3, direction: 'reverse' }),
    delay: anime.stagger(200, { from: 3, direction: 'reverse' }),
  }, 0)
  .add({
    targets: '.range div',
    translateY: anime.stagger(['-2em', '2em']),
    delay: anime.stagger([0, 600])
  }, 0)
  .add({
    targets: '.range-reversed div',
    translateY: anime.stagger(['-2em', '2em'], { direction: 'reverse'}),
    delay: anime.stagger([0, 600], { direction: 'reverse'}),
  }, 0)
  .add({
    targets: '.range-from-last div',
    translateY: anime.stagger(['-2em', '2em'], {from: 'last'}),
    delay: anime.stagger([0, 600], {from: 'last'})
  }, 0)
  .add({
    targets: '.range-from-last-reversed div',
    translateY: anime.stagger(['-2em', '2em'], { from: 'last', direction: 'reverse'}),
    delay: anime.stagger([0, 600], { from: 'last', direction: 'reverse'}),
  }, 0)
  .add({
    targets: '.range-from-center div',
    translateY: anime.stagger(['-2em', '2em'], {from: 'center'}),
    delay: anime.stagger([0, 600], {from: 'center'})
  }, 0)
  .add({
    targets: '.range-from-center-reversed div',
    translateY: anime.stagger(['-2em', '2em'], { from: 'center', direction: 'reverse'}),
    delay: anime.stagger([0, 600], { from: 'center', direction: 'reverse'}),
  }, 0)
  .add({
    targets: '.easing div',
    translateY: anime.stagger(['2rem', '-2rem'], {from: 'center', easing: 'easeOutExpo'}),
    delay: anime.stagger([0, 600], {from: 'center', easing: 'easeOutExpo'})
  }, 0)
  .add({
    targets: '.easing-reversed div',
    translateY: anime.stagger(['2rem', '-2rem'], {from: 'center', direction: 'reverse', easing: 'easeOutExpo'}),
    delay: anime.stagger([0, 600], {from: 'center', direction: 'reverse', easing: 'easeOutExpo'}),
  }, 0)
  .add({
    targets: '.grid div',
    scale: anime.stagger([1, 0], {grid: [10, 5], from: 38}),
    delay: anime.stagger(100, {grid: [10, 5], from: 38})
  }, 0)
  .add({
    targets: '.grid-reversed div',
    scale: anime.stagger([1, 0], {grid: [10, 5], from: 38, direction: 'reverse'}),
    delay: anime.stagger(100, {grid: [10, 5], from: 38, direction: 'reverse'})
  }, 0)
  .add({
    targets: '.grid-axis div',
    translateX: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'x'}),
    translateY: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'y'}),
    delay: anime.stagger(100, {grid: [10, 5], from: 38})
  }, 0)
  .add({
    targets: '.grid-axis-reversed div',
    translateX: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'x', direction: 'reverse'}),
    translateY: anime.stagger('.5rem', {grid: [10, 5], from: 38, axis: 'y', direction: 'reverse'}),
    delay: anime.stagger(100, {grid: [10, 5], from: 38, direction: 'reverse'})
  }, 0);

  function animePlayer(instance, playerClass) {

    function createEl(type, className, parentEl) {
      var el = document.createElement(type);
      if (className) el.classList.add(className);
      if (parentEl) parentEl.appendChild(el);
      return el;
    }

    var timelineEl = createEl('div', 'timeline', document.body);
    if (playerClass) timelineEl.classList.add(playerClass);
    var needleEl = createEl('div', 'tl-needle', timelineEl);
    var animations = [];
    var colors = ['#FF1461','#FF7C72','#FBF38C','#A6FF8F','#18FF92','#1CE2B2','#5EF3FB','#61C3FF','#5A87FF','#8453E3','#C26EFF','#FB89FB'];
    var colorIndex = 0;

    function convertMStoEM(ms) { return ms / 100; }
    function convertEMtoMS(em) { return parseFloat(em) * 250; }

    function createAnimationLog(animObj, timelineOffset) {
      var anim = animObj;
      anim.player = {};
      anim.player.animationEl = createEl('div', 'tl-animation', timelineEl);
      anim.player.delayEl = createEl('div', 'tl-delay', anim.player.animationEl);
      anim.player.endDelayEl = createEl('div', 'tl-end-delay', anim.player.animationEl);
      anim.update = function() {
        anime.set(anim.player.animationEl, {
          left: convertMStoEM(timelineOffset) + 'em',
          width: convertMStoEM(anim.duration * 3) + 'em'
        });
        anime.set(anim.player.delayEl, {width: (anim.delay / anim.duration) * 100 + '%'});
        anime.set(anim.player.endDelayEl, {width: (anim.endDelay / anim.duration) * 100 + '%'});
      }
      anime.set(anim.player.animationEl, {color: colors[colorIndex]});
      colorIndex++;
      if (!colors[colorIndex]) colorIndex = 0;
      anim.update();
      animations.push(anim);
      return anim;
    }

    instance.pause();

    var playerAnimation = anime({
      targets: needleEl,
      translateX: convertMStoEM(instance.duration * 3) + 'em',
      duration: instance.duration,
      direction: instance.direction,
      loop: instance.loop,
      easing: 'linear',
      update: function(a) {
        instance.seek(a.currentTime);
      }
    });

    if (instance.children.length) {
      instance.children.forEach(function(child) {
        child.animations.forEach(function(anim) {
          createAnimationLog(anim, child.timelineOffset);
        });
      })
    } else {
      instance.animations.forEach(function(anim) {
        createAnimationLog(anim);
      });
    }

  }

  animePlayer(animations, 'player-animation');

</script>
</html>
